/********************************************************************************
 *      Copyright:  (C) 2024 linuxer<linuxer@email.com>
 *                  All rights reserved.
 *
 *       Filename:  client.c
 *    Description:  This file 
 *
 *        Version:  1.0.0(17/03/24)
 *         Author:  linuxer <linuxer@email.com>
 *      ChangeLog:  1, Release initial version on "17/03/24 16:52:22"
 *                 
 ********************************************************************************/
#include "client.h"
#define RECONNECTTIME 10 
int main(int argc,char **argv)
{
	int 				rv=-1;
	char				*progname=NULL;
	int 				sockfd=-1;
	int 				port=0;
	char				*servip=NULL;
	char				buf[1024];
	struct	hostent*	host;
	int					opt=0;
	int					sleep_time=30;

	char				temp[32];
	char				report_info[128];
	ReportTemp 			report_temp;
	strncpy(report_temp.serial,SERIAL,64);
	sqlite3*			db;
	char				db_name[32]="client_record";
	char				tb_name[32]="ds18b20_temp_record";

#if 1
	struct	option	long_options[]={
		{"help",no_argument,NULL,'h'},
		{"servip",required_argument,NULL,'i'},
		{"domain",required_argument,NULL,'d'},
		{"port",required_argument,NULL,'p'},
		{"time",required_argument,NULL,'t'},
		{NULL,0,NULL,0}
	};
#endif
	progname=basename(argv[0]);
#if 1 
	if(argc<2)
	{
		print_usage(progname);
		return -1;
	}
	

	if(logger_init("client.log",LOG_LEVEL_DEBUG))
	{
		fprintf(stderr,"Record logs error\n");
		return -2;
	}
	while((opt=getopt_long(argc,argv,"i: d: p: t: h::",long_options,NULL))!=-1)
	{
		switch(opt)
		{
			case 'i':
				{
					servip=optarg;
					log_info("Server's ip: %s\n",servip);
					break;
				}
			case 'd':
				{
					host=gethostbyname(optarg);		
					servip=inet_ntoa(*((struct in_addr*)host->h_addr));
					log_info("server's domain: %s to  %s\n",optarg,servip);
					break;
				}
			case 'p':
				{
					port=atoi(optarg);
					log_info("Server's port %d\n",port);
					break;
				}
			case 't':
				{
					sleep_time=atoi(optarg);
					break;

				}
			case 'h':
				{
					print_usage(progname);
					return 0;
				}


		}	
	}
#endif
	while(1)
	{
		//连接服务器
		rv=m_connect(&sockfd,servip,port);
		if(rv<0)
		{
			close(sockfd);

				//获取信息
			rv=get_info(report_temp.temperature);
			if(rv<0)
			{
				log_error("Get temperature get error:%s\n",strerror(errno));
				continue;
			}

			rv=get_time(report_temp.time);
			if(rv<0)
			{
				log_error("Get time get error:%s\n",strerror(errno));
				continue;
			}

			sprintf(report_temp.serial,"%s",SERIAL);
			
			//创建表
			//	create_db_table(db,db_name,tb_name);
		
			//记录到数据库中去
			tb_add(db,db_name,tb_name,report_temp.serial,report_temp.temperature,report_temp.time);
			sleep(RECONNECTTIME);
			log_error("Connect to server failure:%s\n",strerror(errno));
			continue;
		}
		//存储到数据库
		
		while(1)
		{
			rv=is_socket_exceptional(&sockfd);
			if(rv>0)
			{

				log_info("Connect to server[%s:%d] successfully\n",servip,port);

				//上报温度
				log_info("Start to report temperture\n");
#if 1
				//获取信息
				rv=get_info(report_temp.temperature);
				if(rv<0)
				{
					log_error("Get temperature get error:%s\n",strerror(errno));
					continue;
				}

				rv=get_time(report_temp.time);
				if(rv<0)
				{
					log_error("Get time get error:%s\n",strerror(errno));
					continue;
				}

				sprintf(report_temp.serial,"%s",SERIAL);

				//记录到数据库中去
				tb_add(db,db_name,tb_name,report_temp.serial,report_temp.temperature,report_temp.time);
			
			//	create_db_table(db,db_name,tb_name);
				log_info("Serial: %s     Time: %s      Temperature :%s\n",report_temp.serial,report_temp.time,report_temp.temperature);
#endif
				memset(report_info,0,sizeof(report_info));		
				sprintf(report_info,"Serial: %s		Temperature: %s				Time: %s\n",report_temp.serial,report_temp.temperature,report_temp.time);
				rv=write(sockfd,report_info,sizeof(report_info));
				if(rv<0)
				{
					close(sockfd);
					log_warn("Fail to write to server:%s\n",strerror(errno));
					//检查出错机制
					break;
				}
				log_info("Report temperature successfully!\n");
				sleep(sleep_time);	
			}
			else{
				log_error("Get error:%s\n",strerror(errno));
				close(sockfd);
				break;
			}
			
		}
	}
	logger_term();
}
void print_usage(char *progname)
{
	printf("%s usage\n",progname);
	printf("[-i] | [-d] server's ip or server's domain\n");
	printf("[-p] server's port\n");
	printf("[-t] the time to report\n");
}
 
int m_connect(int *sockfd,char *servip,int port)
{
	//存储到数据库中
	struct sockaddr_in	servaddr;
	memset(&servaddr,0,sizeof(servaddr));
	
	*sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(*sockfd<0)
	{
		log_error("Create a socket failure: %s\n",strerror(errno));
		return -1;
	}
	log_info("Create client socket[%d] successfully!\n",*sockfd);

	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(port);
	//servaddr->sin_addr.s_addr = inet_addr(servip);
	inet_aton(servip,&servaddr.sin_addr);

	if( connect(*sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
	{
		log_error("connect to server [%s:%d] failure: %s\n", servip, port, strerror(errno));
		return -2;
	}
	return 0;
}

//判断网络是否异常
int is_socket_exceptional(int *sockfd)
{
	int 		error;
	socklen_t	len=sizeof(error);

	//获取socket的错误信息
	if(getsockopt(*sockfd,SOL_SOCKET,SO_ERROR,&error,&len)<0)
	{
		perror("getsockopt");
		return -1;
	}

	if(error!=0)
	{
		return -1;
	}

	//无异常
	return 1;

}
